package expertisenetwork;

import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;


public class Network {
	private int m;
	private int n;
	Vector<Integer> ids = new Vector<Integer>();
	private Map<Integer, Expertise> data = new TreeMap<Integer, Expertise>();
	

	// / create a new matrix with m rows and n columns
	public Network(int m, int n) {
		this.m = m;
		this.n = n;
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				data.put(i * n + j, new Expertise());
			}
		}
	}

	public void addUser(int userId) {
		ids.add(userId);
	}

	public void addLink(int fromUser, int toUser, double value) {
		int fromId = getId(fromUser);
		int toId = getId(toUser);
			setValueAt(fromId, toId, value);
	}

	public Expertise getWeight(int fromUser, int toUser) {
		return getValueAt(getId(fromUser), getId(toUser));
	}

	private void setValueAt(int i, int j, double value) {
		if (outOfBoundary(i, j)) {
			throw new IllegalArgumentException("index (" + i + ", " + j
					+ ") out of bounds");
		} else {
			data.get(i * n + j).add(value);

		}
	}

	private Expertise getValueAt(int i, int j) {
		if (outOfBoundary(i, j))
			throw new IllegalArgumentException("index (" + i + ", " + j
					+ ") out of bounds");
		return data.get(i * n + j);
	}

	public Vector<Link> getInLinks(int userId) {
		Vector<Link> inLinks = new Vector<Link>();
		for (int i = 0; i < n; i++) {
			if (getValueAt(i, userId).isInitialized()) {
				inLinks.add(new Link(i, getValueAt(i, userId)));
			}
		}
		return inLinks;
	}

	public Vector<Link> getOutLinks(int userId) {
		Vector<Link> outLinks = new Vector<Link>();
		for (int j = 0; j < n; j++) {
			if (getValueAt(userId, j).isInitialized()) {
				outLinks.add(new Link(j, getValueAt(userId, j)));
			}
		}
		return outLinks;
	}

	public int getId(int userId) {
		return ids.indexOf(userId);
	}

	public boolean outOfBoundary(int i, int j) {
		return (i >= m || j >= n || i < 0 || j < 0);
	}

	public int getNumUsers() {
		return m;
	}
	
	public Vector<Integer> getIds(){
		return ids;
	}
}